home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / turbovis / tvtoys04.zip / HELPFILE.PAS < prev    next >
Pascal/Delphi Source File  |  1993-12-18  |  26KB  |  1,072 lines

  1. (***************************************************************************
  2.   Helpfile unit
  3.   Improved help file
  4.   PJB November 7, 1993, Internet mail to d91-pbr@nada.kth.se
  5.   Free patches, use at your own risk. All warranties void.
  6.   If even more modified, please state so if you pass this around.
  7.  
  8.   This HelpFile patched to allow back tracking and external access to
  9.   help topics (search for "HelpExtensions").
  10.   Some Borland bugs fixed (search for "fix"). Handles empty topics.
  11.   Doesn't spill long topic links any more.
  12.  
  13.   Define RangeFix to fix more Borland bugs (search for "Int->Word fix"):
  14.     Borland sometimes uses integers for help topics even though they are
  15.     words, RangeFix changes them into words so you can compile with $R+.
  16.     If you define RangeFix, you'll get a compile error if you try to
  17.     compile TVHC. In that case, modify TVHC to this (change to RefType):
  18.  
  19.     procedure HandleCrossRefs(var S: TStream; XRefValue: RefType); far; { Int->Word fix }
  20.  
  21.  
  22.   This HelpFile requires an exact topic match. To respond to a range of
  23.   help topics, define several in a row like this:
  24.  
  25.     .topic  First,F2,F3,F4
  26.  
  27.   Added PPalette casts, Config and Prefs. Remembers last selected topic.
  28. ***************************************************************************)
  29. {************************************************}
  30. {                                                }
  31. {   Turbo Vision Demo                            }
  32. {   Copyright (c) 1992 by Borland International  }
  33. {                                                }
  34. {************************************************}
  35.  
  36. unit HelpFile;
  37.  
  38. {$I toyCfg}
  39.  
  40. {$IFDEF DPMI}
  41.  {$B-,X+}
  42. {$ELSE}
  43.  {$B-,F+,O+,X+}
  44. {$ENDIF}
  45.  
  46. {$IFNDEF RangeFix}
  47.  {$R-}              (* Borland bugs require $R- *)
  48. {$ENDIF}
  49.  
  50. interface
  51.  
  52. uses
  53.   Drivers, Objects, Views,
  54.   toyPrefs;
  55.  
  56. const
  57.   CHelpColor      = #$37#$3F#$3A#$13#$13#$30#$3E#$1E;
  58.   CHelpBlackWhite = #$07#$0F#$07#$70#$70#$07#$0F#$70;
  59.   CHelpMonochrome = #$07#$0F#$07#$70#$70#$07#$0F#$70;
  60.   CHelpViewer     = #6#7#8;
  61.   CHelpWindow     = #128#129#130#131#132#133#134#135;
  62.  
  63. type
  64.  
  65.  {$IFDEF RangeFix}
  66.   RefType = Word;                       { Int->Word fix }
  67.  {$ELSE}
  68.   RefType = Integer;
  69.  {$ENDIF}
  70.  
  71. { TParagraph }
  72.  
  73.   PParagraph = ^TParagraph;
  74.   TParagraph = record
  75.     Next: PParagraph;
  76.     Wrap: Boolean;
  77.     Size: Word;
  78.     Text: record end;
  79.   end;
  80.  
  81. { THelpTopic }
  82.  
  83.   TCrossRef = record
  84.     Ref: Word;
  85.     Offset: Integer;
  86.     Length: Byte;
  87.   end;
  88.  
  89.   PCrossRefs = ^TCrossRefs;
  90.   TCrossRefs = array[1..10000] of TCrossRef;
  91.   TCrossRefHandler = procedure (var S: TStream; XRefValue: RefType);  { Int->Word fix }
  92.  
  93.   PHelpTopic = ^THelpTopic;
  94.   THelpTopic = object(TObject)
  95.     constructor Init;
  96.     constructor Load(var S: TStream);
  97.     destructor Done; virtual;
  98.     procedure AddCrossRef(Ref: TCrossRef);
  99.     procedure AddParagraph(P: PParagraph);
  100.     procedure GetCrossRef(I: Integer; var Loc: TPoint; var Length: Byte;
  101.       var Ref: Word);
  102.     function GetLine(Line: Integer): String;
  103.     function GetNumCrossRefs: Integer;
  104.     function NumLines: Integer;
  105.     procedure SetCrossRef(I: Integer; var Ref: TCrossRef);
  106.     procedure SetNumCrossRefs(I: Integer);
  107.     procedure SetWidth(AWidth: Integer);
  108.     procedure Store(var S: TStream);
  109.   private
  110.     Paragraphs: PParagraph;
  111.     NumRefs: Integer;
  112.     CrossRefs: PCrossRefs;
  113.     Width: Integer;
  114.     LastOffset: Integer;
  115.     LastLine: Integer;
  116.     LastParagraph: PParagraph;
  117.     function WrapText(var Text; Size: Integer; var Offset: Integer;
  118.       Wrap: Boolean): String;
  119.   end;
  120.  
  121. { THelpIndex }
  122.  
  123.   PIndexArray = ^TIndexArray;
  124.   TIndexArray = array[0..16380] of LongInt;
  125.  
  126.   PContextArray = ^TContextArray;
  127.   TContextArray = array[0..16380] of Word;
  128.  
  129.   PHelpIndex = ^THelpIndex;
  130.   THelpIndex = object(TObject)
  131.     constructor Init;
  132.     constructor Load(var S: TStream);
  133.     destructor Done; virtual;
  134.     function Position(I: Word): Longint;
  135.     procedure Add(I: Word; Val: Longint);
  136.     procedure Store(var S: TStream);
  137.   private
  138.     Size: Word;
  139.     Used: Word;
  140.     Contexts: PContextArray;
  141.     Index: PIndexArray;
  142.     function Find(I: Word): Word;
  143.   end;
  144.  
  145. { THelpFile }
  146.  
  147.   PHelpFile = ^THelpFile;
  148.   THelpFile = object(TObject)
  149.     Stream: PStream;
  150.     Modified: Boolean;
  151.    {$IFDEF HelpExtensions}
  152.     HelpAlreadyPopped: Boolean;                 (* "First time" indicator *)
  153.    {$ENDIF}
  154.     constructor Init(S: PStream);
  155.     destructor Done; virtual;
  156.     function GetTopic(I: Word): PHelpTopic;
  157.     function InvalidTopic: PHelpTopic;
  158.     procedure RecordPositionInIndex(I: RefType);    { Int->Word fix }
  159.     procedure PutTopic(Topic: PHelpTopic);
  160.   private
  161.     Index: PHelpIndex;
  162.     IndexPos: LongInt;
  163.   end;
  164.  
  165. { THelpViewer }
  166.  
  167.   PHelpViewer = ^THelpViewer;
  168.   THelpViewer = object(TScroller)
  169.     HFile: PHelpFile;
  170.     Topic: PHelpTopic;
  171.     Selected: Integer;
  172.     constructor Init(var Bounds: TRect; AHScrollBar,
  173.       AVScrollBar: PScrollBar; AHelpFile: PHelpFile; Context: Word);
  174.     destructor Done; virtual;
  175.     procedure ChangeBounds(var Bounds: TRect); virtual;
  176.     procedure Draw; virtual;
  177.     function GetPalette: PPalette; virtual;
  178.     procedure HandleEvent(var Event: TEvent); virtual;
  179.   end;
  180.  
  181. { THelpWindow }
  182.  
  183.   PHelpWindow = ^THelpWindow;
  184.   THelpWindow = object(TWindow)
  185.     constructor Init(HFile: PHelpFile; Context: Word);
  186.     function GetPalette: PPalette; virtual;
  187.   end;
  188.  
  189. const
  190.   RHelpTopic: TStreamRec = (
  191.      ObjType: 10000;
  192.      VmtLink: Ofs(TypeOf(THelpTopic)^);
  193.      Load:    @THelpTopic.Load;
  194.      Store:   @THelpTopic.Store
  195.   );
  196.  
  197. const
  198.   RHelpIndex: TStreamRec = (
  199.      ObjType: 10001;
  200.      VmtLink: Ofs(TypeOf(THelpIndex)^);
  201.      Load:    @THelpIndex.Load;
  202.      Store:   @THelpIndex.Store
  203.   );
  204.  
  205. procedure RegisterHelpFile;
  206.  
  207. procedure NotAssigned(var S: TStream; Value: RefType);    { Int->Word fix }
  208.  
  209. const
  210.   CrossRefHandler: TCrossRefHandler = NotAssigned;
  211.  
  212. implementation
  213.  
  214. { THelpTopic }
  215.  
  216. constructor THelpTopic.Init;
  217. begin
  218.   inherited Init;
  219.   LastLine := MaxInt;
  220. end;
  221.  
  222. constructor THelpTopic.Load(var S: TStream);
  223.  
  224. procedure ReadParagraphs;
  225. var
  226.   I, Size: Integer;
  227.   PP: ^PParagraph;
  228. begin
  229.   S.Read(I, SizeOf(I));
  230.   PP := @Paragraphs;
  231.   while I > 0 do
  232.   begin
  233.     S.Read(Size, SizeOf(Size));
  234.     GetMem(PP^, SizeOf(PP^^) + Size);
  235.     PP^^.Size := Size;
  236.     S.Read(PP^^.Wrap, SizeOf(Boolean));
  237.     S.Read(PP^^.Text, Size);
  238.     PP := @PP^^.Next;
  239.     Dec(I);
  240.   end;
  241.   PP^ := nil;
  242. end;
  243.  
  244. procedure ReadCrossRefs;
  245. begin
  246.   S.Read(NumRefs, SizeOf(Integer));
  247.   GetMem(CrossRefs, SizeOf(TCrossRef) * NumRefs);
  248.   if CrossRefs <> nil then
  249.     S.Read(CrossRefs^, SizeOf(TCrossRef) * NumRefs);
  250. end;
  251.  
  252. begin
  253.   inherited Init;                 { BUG fix, for empty topics }
  254.   ReadParagraphs;
  255.   ReadCrossRefs;
  256.                                   {  Width:=0 handled by init }
  257.   LastLine := MaxInt;
  258. end;
  259.  
  260. destructor THelpTopic.Done;
  261.  
  262. procedure DisposeParagraphs;
  263. var
  264.   P, T: PParagraph;
  265. begin
  266.   P := Paragraphs;
  267.   while P <> nil do
  268.   begin
  269.     T := P;
  270.     P := P^.Next;
  271.     FreeMem(T, SizeOf(T^) + T^.Size);
  272.   end;
  273. end;
  274.  
  275. begin
  276.   DisposeParagraphs;
  277.   FreeMem(CrossRefs, SizeOf(TCrossRef) * NumRefs);
  278.   inherited Done
  279. end;
  280.  
  281. procedure THelpTopic.AddCrossRef(Ref: TCrossRef);
  282. var
  283.   P: PCrossRefs;
  284. begin
  285.   GetMem(P, (NumRefs+1) * SizeOf(TCrossRef));
  286.   if NumRefs > 0 then
  287.   begin
  288.     Move(CrossRefs^, P^, NumRefs * SizeOf(TCrossRef));
  289.     FreeMem(CrossRefs, NumRefs * SizeOf(TCrossRef));
  290.   end;
  291.   CrossRefs := P;
  292.   CrossRefs^[NumRefs] := Ref;
  293.   Inc(NumRefs);
  294. end;
  295.  
  296. procedure THelpTopic.AddParagraph(P: PParagraph);
  297. var
  298.   PP: ^PParagraph;
  299. begin
  300.   PP := @Paragraphs;
  301.   while PP^ <> nil do
  302.     PP := @PP^^.Next;
  303.   PP^ := P;
  304.   P^.Next := nil;
  305. end;
  306.  
  307. procedure THelpTopic.GetCrossRef(I: Integer; var Loc: TPoint;
  308.   var Length: Byte; var Ref: Word);
  309. var
  310.   OldOffset, CurOffset, Offset, ParaOffset: Integer;
  311.   P: PParagraph;
  312.   Line: Integer;
  313. begin
  314.   ParaOffset := 0;
  315.   CurOffset := 0;
  316.   OldOffset := 0;
  317.   Line := 0;
  318.   Offset := CrossRefs^[I]